﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data;
using Framework.Repositories;
using Framework.Infrastructure.IoC;
using Microsoft.Practices.Unity;
using Framework.Bus;
using System.Transactions;

namespace Framework.UnitOfWork
{
    public class DbCtxUnitOfWork : IUnitOfWork
    {
        #region IUnitOfWork Members

        public DbCtxUnitOfWork(Framework.Infrastructure.Context.MSDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        DbContext _dbContext;
        public object DbContext
        {
            get { return _dbContext; }
        }

        public bool DTCompatible
        {
            get { throw new NotImplementedException(); }
        }

        public bool Committed
        {
            get { throw new NotImplementedException(); }
        }

        public void Commit()
        {
            using (TransactionScope transaction = new TransactionScope())
            {
                _dbContext.SaveChanges();
                EventBus.Commit();
                transaction.Complete();
            }
        }

        public void Rollback()
        {
            throw new NotImplementedException();
        }

        public void RegisterUnChanged(object obj)
        {
            _dbContext.Entry(obj).State = EntityState.Unchanged;
        }

        public void RegisterNew(object obj)
        {
            _dbContext.Entry(obj).State = EntityState.Added;
        }

        public void RegisterModified(object obj)
        {
            _dbContext.Entry(obj).State = EntityState.Modified;
        }

        public void RegisterDeleted(object obj)
        {
            _dbContext.Entry(obj).State = EntityState.Deleted;
        }

        public IRepository<TAggregateRoot> GetRepository<TAggregateRoot>() where TAggregateRoot : class, IAggregateRoot, new()
        {
            try
            {

                var repository = IoCFactory.Instance.CurrentContainer.Resolve<IRepository<TAggregateRoot>>();
                return repository;
            }
            catch
            {
                throw;
            }
        }

        #endregion

        #region ISql Members

        public IEnumerable<TEntity> SqlQuery<TEntity>(string sql)
        {
            return _dbContext.Database.SqlQuery<TEntity>(sql);
        }

        public IEnumerable<TEntity> SqlQuery<TEntity>(string sql, params object[] parameters)
        {
            return _dbContext.Database.SqlQuery<TEntity>(sql, parameters);
        }

        public int ExecuteSqlCommand(string sql, params object[] parameters)
        {
            return _dbContext.Database.ExecuteSqlCommand(sql, parameters);
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            if (_dbContext != null)
            {
                _dbContext.Dispose();
            }
        }

        #endregion

        #region IUnitOfWork Members

        IEventBus _eventBus;
        public IEventBus EventBus
        {
            get
            {
                return _eventBus ?? (_eventBus = IoCFactory.Instance.CurrentContainer.Resolve<IEventBus>());
            }
        }

        #endregion
    }
}
